package com.zhaorui.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.xml.bind.v2.model.core.ID;
import com.zhaorui.aop.Annotation2;
import com.zhaorui.entity.Account;
import com.zhaorui.entity.ActivityUser;
import com.zhaorui.entity.ZR;
import com.zhaorui.form.ModifyPassForm;
import com.zhaorui.form.UserAddForm;
import com.zhaorui.form.UserForm;
import com.zhaorui.form.UserQueryForm;
import com.zhaorui.service.ActivityUserService;
import com.zhaorui.vo.PageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/activityUser")
@Slf4j
@CrossOrigin
@Api(tags = "账号管理接口")
public class ActivityUserController {
    @Autowired
    private ActivityUserService activityUserService;
    @Autowired
    private RedisTemplate redisTemplate;
    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    @Value("${OSS.endpoint}")
    String endpoint;
    // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
    @Value("${OSS.accessKeyId}")
    String accessKeyId;
    @Value("${OSS.accessKeySecret}")
    String accessKeySecret;
    // 填写Bucket名称，例如examplebucket。
    @Value("${OSS.bucketName}")
    String bucketName;

    /**
     * 用户登录
     *
     * @param userForm
     * @return
     */
    @PostMapping("/login")
    @ApiOperation("用户登录")
    public ZR login(@RequestBody UserForm userForm) {
        log.info ("开始登录{}", userForm);
        List<ActivityUser> activityUsers = new ArrayList<> ();
        QueryWrapper wrapper = new QueryWrapper ();
        wrapper.select ("user_name", "user_pass");
        activityUsers = activityUserService.list (wrapper);
        for (int i = 0; i < activityUsers.size (); i++) {
            ActivityUser activityUser = activityUsers.get (i);
            String userName = activityUser.getUserName ();
            String userPass = activityUser.getUserPass ();
            if (userName.equals (userForm.getUserName ()) && userPass.equals (userForm.getUserPass ())) {
                return new ZR (1000, "登录成功", userForm);
            }
        }
        return new ZR (-1000, "登录失败", userForm);
    }

    /**
     * 综合查询
     *
     * @param userQueryForm
     * @param currentPage
     * @param pagesize
     * @return
     */
    @GetMapping("/queryUsers")
    @ApiOperation("用户信息综合查询")
    public ZR queryUsers(UserQueryForm userQueryForm, @RequestParam(name = "currentPage", defaultValue = "1") Integer currentPage, @RequestParam(name = "pagesize", defaultValue = "5") Integer pagesize) {
        log.info ("综合查询:{}", userQueryForm);
        ActivityUser activityUser = new ActivityUser ();
        //复制vo对象接收的参数到DTO对象中
        BeanUtil.copyProperties (userQueryForm, activityUser);
        //分页对象
        Page page = new Page (currentPage, pagesize);
        List<HashMap> users = activityUserService.queryUsers (activityUser);
        PageVo pageVo = new PageVo ();
        pageVo.setResult (users);
        pageVo.setTotal (page.getTotal ());
        return new ZR (1000, "查询成功", users);
    }


    /**
     * 查询所有
     *
     * @return
     */
    @GetMapping("/queryUsersAll")
    @ApiOperation("查询所有")
    public ZR queryUsersAll() {
        log.info ("查询所有.......");
        List<HashMap> mapList = activityUserService.queryUsersAll ();
        return new ZR (1000, "查询成功", mapList);
    }


    /**
     * 根据id查询
     *放入redis
     * @param id
     * @return
     */
    @GetMapping("/queryUsersId/{id}")
    @ApiOperation("根据id查询详情")

    public ZR queryByEmpno(@PathVariable Integer id) {
        log.info ("开始根据id查询:{}", id);
        ActivityUser activityUser = null;
        //判断redis中是否存在
        if (redisTemplate.hasKey (id + "")) {//redis存在直接数据
            //转换成字符串id+"":一定是字符串
            String o = redisTemplate.opsForValue ().get (id + "").toString ();
            log.info ("转换成字符串o:{}", o);
            //字符串转换成对象,放入activityUser 中
            activityUser = JSONUtil.toBean (o, ActivityUser.class);
            log.info ("字符串转换成对象,放入activityUser:{}", activityUser);
        } else {//不存在，调用方法从数据库中取值
            activityUser = activityUserService.queryUsersId (id);
            //把 取到的数值保存在redis中
            if (activityUser != null) {
                //emp转成字符串保存
                String s = JSONUtil.toJsonStr (activityUser);
                log.info ("保存的参数:{}", s);
                //放入redis中;10分钟
                redisTemplate.opsForValue ().set (activityUser.getId () + "", s,10, TimeUnit.MINUTES);
            }
        }
        if (activityUser != null) {
            return new ZR (1000, "查询成功", activityUser);
        }
        return new ZR (-1000, "查询失败", null);

    }


    /**
     * 添加
     *
     * @param userAddForm
     * @return
     */
    @PostMapping("/saveUser")
    @ApiOperation("增加")
    @Transactional//事务
    @Annotation2(tableName = "activity_user", optionName = "增加")
    public ZR saveEmp(@Valid @RequestBody UserAddForm userAddForm) {
        log.info ("开始新增*********************************");
        ActivityUser activityUser = new ActivityUser ();
        BeanUtil.copyProperties (userAddForm, activityUser);
        activityUserService.saveUser (activityUser);
        return new ZR (1000, "增加成功", activityUser);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @DeleteMapping("/deleteUser/{id}")
    @ApiOperation("删除")
    @Annotation2(tableName = "activity_user", optionName = "删除", primaryKeyName = "id")
    @Transactional
    public ZR deleteEmp(@PathVariable Integer id) {
        log.info ("开始删除:{}", id);
        boolean state = activityUserService.delete (id);
        if (state) {
            //删除缓存;就是Integer
            redisTemplate.delete (id + "");
            return new ZR (1000, "删除成功", id);
        }
        int i=1/0;
        return new ZR (-1000, "删除失败", null);
    }

    /**
     * 修改
     * @param activityUser
     * @return
     */
    @Annotation2(tableName = "activity_user", optionName = "编辑")
    @PutMapping("/modifyUsers")
    @ApiOperation("编辑")
    @Transactional
    public ZR modifyEmps(@RequestBody ActivityUser activityUser) {
        log.info ("开始编辑:{}", activityUser);
        if (activityUserService.updateById (activityUser)) {
            if (redisTemplate.hasKey (activityUser.getId () + "")) {
                //存在删除缓存
                redisTemplate.delete (activityUser.getId () + "");
            }
        }

        return new ZR (1000, "修改成功", activityUser);
    }


    /**
     * 修改密码
     * @param modifyPassForm
     * @return
     */
    @PutMapping("/modifyIdPass")
    @ApiOperation("修改密码")
    @Annotation2(tableName = "activity_user", optionName = "修改密码")
    public ZR modifyIdPass(ModifyPassForm modifyPassForm) {
        ActivityUser activityUser = new ActivityUser ();
        //复制vo对象接收的参数到DTO对象中
        BeanUtil.copyProperties (modifyPassForm, activityUser);
        activityUserService.modifyIdPass(modifyPassForm);
        return new ZR (1000,"修改成功",modifyPassForm);
    }


    /**
     * 上传图片
     * @param file
     * @return
     * @throws IOException
     */
    //上传图片
    @PostMapping("/uploadImg")
    @ApiOperation("图片上传")
    public ZR uploadImg(@RequestParam("file") MultipartFile file) throws IOException {
        log.info ("上传图片：{}", file);
// 填写文件名。文件名包含路径，不包含Bucket名称。例如exampledir/exampleobject.txt。
        String objectName = UUID.randomUUID ().toString () + file.getOriginalFilename ();//防止从名

        OSS ossClient = null;
        try {
            // 创建OSSClient实例。
            ossClient = new OSSClientBuilder ().build (endpoint, accessKeyId, accessKeySecret);


            ossClient.putObject (bucketName, objectName, file.getInputStream ());
        } catch (OSSException e) {
            e.printStackTrace ();
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown ();
        }
        //该文件在OSS上的url要求保存到数据库中，所以上传成功后要返回到页面
        String url = "https://" + bucketName + "." + endpoint + "/" + objectName;
        return new ZR (1000, "上传成功", url);
    }
}
